package tool

import dao.ModeDao

import java.io.File
import implicits.Implicits._
import org.slf4j.LoggerFactory
import play.api.data.FormBinding
import play.api.http.HttpVerbs
import play.api.mvc._
import ujson.play.PlayJson
import upickle.default._
import utils.Utils

import java.nio.file.Files
import scala.collection.immutable.SeqMap

/**
 * Created by yz on 13/12/2021
 */
object Tool {

  val logger=LoggerFactory.getLogger(this.getClass)

  val dbName = "snp_database"
  val windowsPath = s"E:\\${dbName}"
  val playPath = new File("../").getAbsolutePath
  val linuxPath = playPath + s"/${dbName}"
  val path = {
    if (new File(windowsPath).exists()) windowsPath else linuxPath
  }
  val windowsTestDir = new File("C:\\temp")
  val linuxTestDir = new File(playPath, "workspace")
  val testDir = if (windowsTestDir.exists()) windowsTestDir else linuxTestDir
  val dataDir = new File(path, "data")
  val seqDir = new File(dataDir, "seq")
  val rsDir = new File(dataDir, "rs")
  val binPath = new File(path, "bin")

  def getKoMap(file: File) = {
    val lines = file.lines

    def loop(lines: List[String], map: SeqMap[String, List[String]]): SeqMap[String, List[String]] = {
      lines match {
        case x :: xs =>
          val columns=x.trim.mySplit("\\s{3,}")
          if (columns.size > 1) {
            val key = columns.head
            val v = columns.tail.mkString(" ")
            val curMap = map + (key -> List(v))
            loop(xs, curMap)
          } else {
            val curMap = map.updatedWith(map.keyList.last) { vsOp =>
              vsOp.map { vs =>
                val v = columns.mkString(" ")
                vs :+ v
              }
            }
            loop(xs, curMap)
          }
        case Nil => map
      }
    }

    loop(lines, SeqMap.empty)

  }

  def createTempDirectory(prefix: String)(implicit modeDao: ModeDao) = {
    if (isTestMode) Tool.testDir else Files.createTempDirectory(prefix).toFile
  }

  def isTestMode(implicit modeDao: ModeDao) = {
    val mode = Utils.execFuture(modeDao.select)
    if (mode.test == "t") true else false
  }

  def deleteDirectory(direcotry: File)(implicit modeDao: ModeDao) = {
    if (!isTestMode) Utils.deleteDirectory(direcotry)
  }

  def multipartFormParse(body: MultipartFormData[_]) = body.asFormUrlEncoded

  def transformRq(implicit request: Request[AnyContent], formBinding: FormBinding) = {

    val unwrap = request.body match {
      case body: play.api.mvc.AnyContent =>
        body.asFormUrlEncoded.orElse(body.asMultipartFormData).orElse(body.asJson).getOrElse(body)
      case body => body
    }
    unwrap match {
      case body: play.api.libs.json.JsValue =>
        PlayJson.transform(body, reader[ujson.Value])
      case x =>
        val data: Map[String, Seq[String]] = unwrap match {
          case body: Map[_, _] => body.asInstanceOf[Map[String, Seq[String]]]
          case body: MultipartFormData[_] => multipartFormParse(body)
          case Right(body: MultipartFormData[_]) => multipartFormParse(body)
          case _ => Map.empty
        }
        val method: Map[_ <: String, Seq[String]] = request.method.toUpperCase match {
          case HttpVerbs.POST | HttpVerbs.PUT | HttpVerbs.PATCH => Map.empty
          case _ => request.queryString
        }
        val map = (data ++ method).foldLeft(Map.empty[String, String]) {
          case (s, (key, values)) =>
            if (key.endsWith("[]")) {
              val k = key.dropRight(2)
              s ++ values.zipWithIndex.map { case (v, i) => s"$k[$i]" -> v }
            } else {
              s + (key -> values.headOption.getOrElse(""))
            }
        }
        logger.info(s"${map}")
        writeJs(map)
    }
  }


}


